package com.otitan.forest.right.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.otitan.forest.right.dto.BssForestRightInfoEntityDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @Description: java类作用描述
 * @Author: jiachangsen
 * @CreateDate: 2020/08/12 14:01
 * @UpdateUser: jiachangsen
 * @UpdateDate: 2020/08/12 14:01
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
public class MyExcelUtil {
    /**
     * Excel格式 xls
     */
    public static final String XLS = "xls";

    /**
     * Excel格式 xlsx
     */
    public static final String XLSX = "xlsx";

    /**
     * zip格式 zip
     */
    private static final String ZIP_FILE_SUFFIX = ".zip";

    /**
     * 读取Excel模板
     *
     * @param [fileName]
     * @return org.apache.poi.ss.usermodel.Workbook
     * @throws
     * @author jiachangsen
     * @date 2020/08/12 14:07
     */
    public static Workbook readExcelByFileName(String fileName) {
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
        try {
            InputStream inp = MyExcelUtil.class.getResourceAsStream("/excel/" + fileName);
            return getWorkbook(inp, fileType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 当前方法实现说明
     *
     * @param []
     * @return void
     * @throws
     * @author jiachangsen
     * @date 2020/08/12 14:15
     */
    public static void writeExcel(Workbook workbook, List<Row> rows) {
        Sheet sheet = workbook.getSheetAt(0);
        int lastRowNum = sheet.getLastRowNum();
        CellStyle cellStyle = getCellStyle(workbook);
        for (Row item : rows) {
            Row row = sheet.createRow(++lastRowNum);
            row.setRowStyle(item.getRowStyle());
            for (int i = 0; i < item.getLastCellNum(); i++) {
                Cell createCell = row.createCell(i);
                Cell itemCell = item.getCell(i);
                if (i != item.getLastCellNum() - 1) {
                    createCell.setCellStyle(cellStyle);
                }
                if (itemCell != null) {
                    createCell.setCellValue(itemCell.getStringCellValue());
                } else {
                    createCell.setCellValue("");
                }
            }
        }
    }

    /**
     * 单元格样式
     *
     * @param [workbook]
     * @return org.apache.poi.ss.usermodel.CellStyle
     * @throws
     * @author jiachangsen
     * @date 2020/08/12 16:30
     */
    public static CellStyle getCellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setWrapText(true);
//        Font font = workbook.createFont();
//        font.setFontName("仿宋");
//        cellStyle.setFont(font);
        return cellStyle;

    }

    public static void keepExcel(Workbook workbook, String path) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(path);
            workbook.write(out);
            // 刷新
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 根据文件后缀名类型获取对应的工作簿对象
     *
     * @param inputStream 读取文件的输入流
     * @param fileType    文件后缀名类型（xls或xlsx）
     * @return 包含文件数据的工作簿对象
     * @throws IOException
     */
    public static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException {
        Workbook workbook = null;
        if (fileType.equalsIgnoreCase(MyExcelUtil.XLS)) {
            workbook = new HSSFWorkbook(inputStream);
        } else if (fileType.equalsIgnoreCase(MyExcelUtil.XLSX)) {
            workbook = new XSSFWorkbook(inputStream);
        }
        return workbook;
    }


    /**
     * 保存 Excel 文件
     *
     * @param [value]
     * @return java.lang.String
     * @throws
     * @author jiachangsen
     * @date 2020/09/02 11:23
     */
    public static String saveExcelFile(String basePath, List<BssForestRightInfoEntityDto> list) {
        String filePath = null;
        try {
            if (CollUtil.isNotEmpty(list)) {
                BssForestRightInfoEntityDto dto = list.get(0);
                String village = StrUtil.isNotEmpty(dto.getVillage()) ? dto.getVillage() : "";

                InputStream inp = MyExcelUtil.class.getResourceAsStream("/excel/【导出模板】贵州省林权登记信息入库数字化表.xlsx");
                XSSFWorkbook wb = new XSSFWorkbook(inp);
                SXSSFWorkbook swb = new SXSSFWorkbook(wb, -1);
                XSSFWorkbook xssfWorkbook = swb.getXSSFWorkbook();
                XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
                XSSFCellStyle cellStyle = FileUtil.setCellStyle(xssfWorkbook);
                FileUtil.setCellStyleAndValue(list, sheet, cellStyle);
                String fileName = "林权登记信息入库数字化表（"
                       + village + "）-" + DateUtil.getNowDateStr() + ".xlsx";
                String dir = CommonUtil.mkdirs(basePath);
                filePath = dir + File.separator + fileName;
                MyExcelUtil.keepExcel(wb, filePath);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }

    /**
     * 创建压缩文件，并下载
     *
     * @param [response, filePaths]
     * @return void
     * @throws
     * @author jiachangsen
     * @date 2020/09/02 11:24
     */
    public static void mackZipAndDownload(HttpServletResponse response, List<String> filePaths, String zipFileName) {
        ZipOutputStream out = null;
        try {
            if (CollUtil.isNotEmpty(filePaths)){
                // 设置响应消息头
                String fileName = zipFileName + "林权登记信息" + ZIP_FILE_SUFFIX;
                FileUtil.setResponseContentDisposition(response, fileName);
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/zip;charset=utf-8");

                out = new ZipOutputStream(response.getOutputStream());
                out.setMethod(ZipOutputStream.DEFLATED);

                for (String filePath : filePaths) {
                    File file = new File(filePath);
                    FileInputStream fis = new FileInputStream(file);
                    // 每个文件命名
                    String name = file.getName();
                    String zipEntryName = name.substring(0, name.lastIndexOf("-")) + "." + XLSX;
                    out.putNextEntry(new ZipEntry(zipEntryName));
                    // 写入压缩包
                    int len;
                    byte[] buffer = new byte[1024];
                    while ((len = fis.read(buffer)) > 0) {
                        out.write(buffer, 0, len);
                    }
                    out.closeEntry();
                    fis.close();
                }
                out.close();
                out.flush();
            } else {
                FileUtil.setResponseContentDisposition(response, "数据不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
